﻿using SourceCodeIoc.Aop;
using SourceCodeIoc.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SourceCodeIoc.Factory
{
    public class MySQLFactory : AbstractIOCFactory
    {
        /// <summary>
        /// ioc容器
        /// </summary>
        public Dictionary<string, object> iocContainer = new Dictionary<string, object>();
        /// <summary>
        /// 临时ioc容器
        /// </summary>
        public Dictionary<string, object> iocTmpContainer = new Dictionary<string, object>();
        /// <summary>
        /// ioc type容器
        /// </summary>
        public Dictionary<string, Type> iocTypeContainer = new Dictionary<string, Type>();

        public int ScopeFlag = 0; // 关闭状态

        /// <summary>
        /// IOC Scope容器
        /// </summary>
        public Dictionary<string, object> iocScopeContainer = new Dictionary<string, object>();

        public MySQLFactory()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type[] types = assembly.GetTypes();
            foreach (var type in types)
            {
                //iocTypeContainer.Add(type.FullName, type);
                IOCService iOCService = type.GetCustomAttribute<IOCService>();
                if (iOCService != null)
                {
                    iocTypeContainer.Add(type.FullName, type);
                }
            }

            foreach (var type in types)
            {
          
            }
        }

        public object CreateObject(Type type)
        {
            // 1、判断临时容器是否存在对象
            if (iocTmpContainer.ContainsKey(type.FullName))
            {
                return iocTmpContainer[type.FullName];
            }

            // 1.1、创建对象  公司A  type.Assembly 公司B Activator
            //      1、type.Assembly
            //      2、Activator
            //object _object = Activator.CreateInstance(type);

            object _object = objectCreateStrategy.CreateObject(type); //策略模式

            //object _object = _objectCreateStrategy.CreateObject(type);

            // 2、存储临时对象
            iocTmpContainer.Add(type.FullName, _object);

            PropertyInfo[] propertyInfos = type.GetProperties();
            foreach (var property in propertyInfos)
            {
                /*foreach (var type1 in types)
                {
                    if (property.PropertyType.Equals(type1))
                    {*/
                IOCInject iOCInject = property.GetCustomAttribute<IOCInject>();
                if (iOCInject != null)
                {
                    Type type1 = iocTypeContainer[property.PropertyType.FullName];
                    // School
                    object _objectvalue = CreateObject(type1);
                    property.SetValue(_object, _objectvalue);
                }
                /*  }
              }*/
            }
            return _object;
        }

        public override object GetObject(string FullName)
        {
            Type type = iocTypeContainer[FullName];
            // 1.1、获取自定义特性
            IOCService iOCService = type.GetCustomAttribute<IOCService>();
            if (iOCService != null)
            {
                // 1.2、获取生命周期类型
                if (iOCService._serviceLifetime == "Trainsent")
                {
                    object _object = CreateObject(type);

                    // 2 AOP过滤
                    AOP aOP = type.GetCustomAttribute<AOP>();
                    if (aOP != null)
                    {
                        // 1.2 使用动态代理创建 _object代理对象
                        _object = AOPProxyGenerator.CreateAOPProxy(_object);
                    }
                    return _object;
                }
                else if (iOCService._serviceLifetime == "Scope" && ScopeFlag == 1)
                {
                    // 对象是否已经创建
                    if (iocScopeContainer.ContainsKey(FullName))
                    {
                        return iocScopeContainer[FullName];
                    }

                    object _object = CreateObject(type);

                    // 2 AOP过滤
                    AOP aOP = type.GetCustomAttribute<AOP>();
                    if (aOP != null)
                    {
                        // 1.2 使用动态代理创建 _object代理对象
                        _object = AOPProxyGenerator.CreateAOPProxy(_object);
                    }

                    // 3、存储对象
                    iocScopeContainer.Add(type.FullName, _object);

                    // 4、返回对象
                    return iocScopeContainer[FullName];
                }
                else if (iOCService._serviceLifetime == "Singlaton")
                {
                    // 对象是否已经创建
                    if (iocContainer.ContainsKey(FullName))
                    {
                        return iocContainer[FullName];
                    }

                    object _object = CreateObject(type);

                    // 2 AOP过滤
                    AOP aOP = type.GetCustomAttribute<AOP>();
                    if (aOP != null)
                    {
                        // 1.2 使用动态代理创建 _object代理对象
                        _object = AOPProxyGenerator.CreateAOPProxy(_object);
                    }

                    // 3、存储对象
                    iocContainer.Add(type.FullName, _object);

                    // 4、返回对象
                    return iocContainer[FullName];
                }
            }
            return null;
        }

        public override void StartScope()
        {
            ScopeFlag = 1;
        }

        public override void StopScope()
        {
            ScopeFlag = 0;
            iocScopeContainer.Clear();
        }
    }
}
